package com.amt.olcacon.service.impl;

import cn.hutool.core.io.unit.DataUnit;
import cn.hutool.json.JSONUtil;
import com.amt.olcacon.bo.DataQuality;
import com.amt.olcacon.bo.GetDataQuality;
import com.amt.olcacon.db.DerbyConfig;
import com.amt.olcacon.entity.*;
import com.amt.olcacon.mapper.*;
import com.amt.olcacon.service.IDocService;

import com.amt.olcacon.utils.MinioUtil;
import com.amt.olcacon.utils.PivotTableConverter;
import com.amt.olcacon.utils.MinioProperties;
import com.amt.olcacon.utils.RegexUrlConverter;
import com.amt.olcacon.utils.TablePlaceholderReplacerUtil;

import com.amt.olcacon.vo.GlobalResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.micrometer.common.util.StringUtils;
import org.apache.derby.impl.sql.execute.CurrentDatetime;
import org.apache.poi.xwpf.usermodel.*;

import org.openlca.core.DataDir;
import org.openlca.core.math.Simulator;
import org.openlca.core.model.CalculationSetup;
import org.openlca.core.model.ImpactMethod;
import org.openlca.core.model.Process;
import org.openlca.core.model.Uncertainty;
import org.openlca.core.model.descriptors.Descriptor;
import org.openlca.core.model.descriptors.ImpactDescriptor;
import org.openlca.core.results.Statistics;
import org.openlca.nativelib.NativeLib;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;


import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@Service
public class DocServiceImpl implements IDocService {
    private static final Logger log = LoggerFactory.getLogger(DocServiceImpl.class);

    private ProductMapper productMapper;
    private GeneralModelMapper generalModelMapper;

    @Autowired
    private ContributionTreeMapper contributionTreeMapper;

    @Autowired
    private ProductProcessMapper productProcessMapper;

    @Autowired
    private ImpactCategoryMapper impactCategoryMapper;

    @Autowired
    DocMapper docMapper;

    @Autowired
    private TaskReportMapper taskReportMapper;

    @Autowired
    private MinioUtil minioUtil;

    @Autowired
    private MinioProperties minioProperties;

    @Override
    public GlobalResponse<String> generateReport(Long processId , Long modelId, Long impactMethodId, Long taskId, Long resultId, Long tblProcessId, String templatePath) throws IOException {

        // 打印接收到的全部参数
        log.info("接收到的参数：processId:{}，modelId:{},impactMethodId:{},taskId:{},tblProcessId:{},templatePath:{},resultId:{}", processId, modelId, impactMethodId, taskId, tblProcessId, templatePath,resultId);


//        templatePath = "/upload/LCA报告模板.docx?fileName=LCA报告模板.docx&fut=1763025186740&ai=5cee4b16-a895-4d29-a002-c2845cf526ec&con=lcap_default_connection";
        templatePath = RegexUrlConverter.convertUrlToFilenameWord(templatePath);
        InputStream is = minioUtil.getFileStream(templatePath);
//        InputStream is = Files.newInputStream(Paths.get(templatePath));
        XWPFDocument doc = new XWPFDocument(is);

        DocBasicDataEntity docBasicDataEntity = docMapper.getBasicData(taskId);

        replaceText(doc, "${productName}", docBasicDataEntity.getProductName());
        replaceText(doc, "${specification}", docBasicDataEntity.getSpecification());
        replaceText(doc, "${modelNo}", docBasicDataEntity.getModelNo());
        replaceText(doc, "${modelName}", docBasicDataEntity.getModelName());
        replaceText(doc, "${productUnitName}", docBasicDataEntity.getProductUnitName());
        replaceText(doc, "${boundary}", docBasicDataEntity.getBoundary());
        replaceText(doc, "${bondaryPicture}", docBasicDataEntity.getBondaryPicture());

        // 1.2.3表格替换
        List<DocExchangeProductEntity> docExchangeProductEntityList = docMapper.selectProduct(processId);
        String[] headers123 = {"工序名称", "主产品", "副产品", "分配方法描述"};
        List<String[]> dataRows123 = new ArrayList<>();
        for (DocExchangeProductEntity docExchangeProductEntity : docExchangeProductEntityList) {
            dataRows123.add(new String[]{
                    docExchangeProductEntity.getProcessName(),
                    docExchangeProductEntity.getProduct(),
                    null != docExchangeProductEntity.getFProduct()?docExchangeProductEntity.getFProduct():"",
                    ""
            });
        }
        TablePlaceholderReplacerUtil.replaceTablePlaceholder(doc, "{{ALLOCATION_TABLE}}",headers123,dataRows123);

        // 1.2.4 表格替换 {{IMPACT_METHOD}}

        List<ImpactCategoryEntity> impactCategoryEntityList = impactCategoryMapper.getImpactCategoryByRefId(impactMethodId);
        String[] headers124 = {"环境影响类型指标", "影响类型指标单位"};
        List<String[]> dataRows124 = new ArrayList<>();
        for (ImpactCategoryEntity impactCategoryEntity : impactCategoryEntityList) {
            dataRows124.add(new String[]{
                    impactCategoryEntity.getName(),
                    impactCategoryEntity.getReferenceUnit()
            });
        }
        TablePlaceholderReplacerUtil.replaceTablePlaceholder(doc, "{{IMPACT_METHOD}}",headers124,dataRows124);

        // 1.2.6 表格替换 {{FLOW_TABLE}}

        List<DocFlowEntity> docFlowEntityList = docMapper.selectFlow(processId);
        String[] headers126 = {"清单名称", "规格型号", "所属工序", "数据集名称", "数据库名称","备注"};
        List<String[]> dataRows126 = new ArrayList<>();
        for (DocFlowEntity docFlowEntity : docFlowEntityList) {
            dataRows126.add(new String[]{
                    docFlowEntity.getFlowName(),
                    "",
                    docFlowEntity.getProcessName(),
                    docFlowEntity.getBgName(),
                    "",
                    ""
            });
        }
        TablePlaceholderReplacerUtil.replaceTablePlaceholder(doc, "{{FLOW_TABLE}}",headers126,dataRows126);

        // 2.1 表格替换 {{DEFULT_PROCESS_FLOW}}
        List<DocDefultProcessFLowEntity> docDefultProcessFLowEntityList = docMapper.selectDefultProcessFLow(taskId);
        String[] headers21 = {"类型", "清单名称", "数量", "单位", "上游数据来源","用途/排放原因"};
        List<String[]> dataRows21 = new ArrayList<>();
        for (DocDefultProcessFLowEntity docDefultProcessFLowEntity : docDefultProcessFLowEntityList) {
            dataRows21.add(new String[]{
                    docDefultProcessFLowEntity.getFlowTypeName(),
                    docDefultProcessFLowEntity.getFlowName(),
                    String.valueOf(docDefultProcessFLowEntity.getAmount()),
                    docDefultProcessFLowEntity.getUnitName(),
                    docDefultProcessFLowEntity.getDbType(),
                    ""
            });
        }

        List<DocDefultProcessFLowEntity> selectDistributionMethodList = docMapper.selectDistributionMethod(taskId);
        String[] headers21_DISTRIBUTION_METHOD = {"产品名称", "类型", "数量", "单位", "规格型号","分配系数"};
        List<String[]> dataRows21_DISTRIBUTION_METHOD = new ArrayList<>();
        for (DocDefultProcessFLowEntity docDefultProcessFLowEntity : selectDistributionMethodList) {
            dataRows21_DISTRIBUTION_METHOD.add(new String[]{
                    docDefultProcessFLowEntity.getFlowName(),
                    docDefultProcessFLowEntity.getProductType(),
                    String.valueOf(docDefultProcessFLowEntity.getAmount()),
                    docDefultProcessFLowEntity.getUnitName(),
                    "",
                    docDefultProcessFLowEntity.getPartitionCoefficient()
            });
        }
        TablePlaceholderReplacerUtil.replaceTablePlaceholder(doc, "{{DEFULT_PROCESS_FLOW}}",headers21,dataRows21);
        TablePlaceholderReplacerUtil.replaceTablePlaceholder(doc, "{{DISTRIBUTION_METHOD}}",headers21_DISTRIBUTION_METHOD,dataRows21_DISTRIBUTION_METHOD);

        // 找到 {{OTHER_PROCESS}} 所在的段落
        List<Long> otherProcessIds = docMapper.getOtherProcessId(taskId);
        for (XWPFParagraph paragraph : doc.getParagraphs()) {
            String text = paragraph.getText();
            if (text != null && text.contains("{{OTHER_PROCESS}}")) {

                // 删除原占位符内容
                for (int i = paragraph.getRuns().size() - 1; i >= 0; i--) {
                    paragraph.removeRun(i);
                }

                // 插入生成的内容
                int sectionIndex = 2;
                for (Long otherProcessId : otherProcessIds) {

                    ProductProcessEntity process = productProcessMapper.selectById(otherProcessId);

                    // 章节标题
                    XWPFParagraph titlePara = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    XWPFRun runTitle = titlePara.createRun();
                    runTitle.setBold(true);
                    runTitle.setFontSize(14);
                    runTitle.setText("2." + sectionIndex + " " + process.getName() );

                    // 基本信息
                    XWPFParagraph p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("（1）过程基本信息");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("过程名称：" + process.getName() );
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("过程边界：" + (process.getBoundary() == null ? "" : process.getBoundary()));

                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("（2）数据代表性");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("主要数据来源：代表企业及供应链实际数据");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("企业名称：");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("产地：中国");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("基准年：2023");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("工艺设备：");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("主要原料：");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("主要能耗：");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("主要原料：");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("生产规模：");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("辅助工艺设备：");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("（可根据以上信息调整单元过程描述）");


                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("表 . 过程清单数据表");

                    // 清单数据表
                    List<DocDefultProcessFLowEntity> flowList = docMapper.selectOtherProcess(otherProcessId,taskId);
                    String[] headers = {"类型", "清单名称", "数量", "单位", "上游数据来源", "用途/排放原因"};
                    List<String[]> rows = new ArrayList<>();
                    for (DocDefultProcessFLowEntity e : flowList) {
                        rows.add(new String[]{
                                e.getFlowTypeName(),
                                e.getFlowName(),
                                String.valueOf(e.getAmount()),
                                e.getUnitName(),
                                e.getDbType(),
                                ""
                        });
                    }
                    TablePlaceholderReplacerUtil.addTable(paragraph,doc,headers,rows);

                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("（3）分配方法");
                    p = doc.insertNewParagraph(paragraph.getCTP().newCursor());
                    p.createRun().setText("表 . 主副产品分配系数表");

                    // 分配方法
                    List<DocDefultProcessFLowEntity> otherProcessDistributionMethod = docMapper.selectOtherProcessDistributionMethod(otherProcessId,taskId);
                    String[] headers_otherProcessDistributionMethod = {"产品名称", "类型", "数量", "单位", "规格型号","分配系数"};
                    List<String[]> rows_otherProcessDistributionMethod = new ArrayList<>();
                    for (DocDefultProcessFLowEntity docDefultProcessFLowEntity : flowList) {
                        rows_otherProcessDistributionMethod.add(new String[]{
                                docDefultProcessFLowEntity.getFlowName(),
                                docDefultProcessFLowEntity.getProductType(),
                                String.valueOf(docDefultProcessFLowEntity.getAmount()),
                                docDefultProcessFLowEntity.getUnitName(),
                                "",
                                docDefultProcessFLowEntity.getPartitionCoefficient()
                        });
                    }
                    TablePlaceholderReplacerUtil.addTable(paragraph,doc,headers_otherProcessDistributionMethod,rows_otherProcessDistributionMethod);
                    sectionIndex++;
                }
                break;
            }
        }
        // 3.1 LCA结果
        List<DocContibutionTreeEntity> contributionTreeList = docMapper.selectContibutionTree(taskId,resultId);
        String[] headers31 = {"环境影响类型指标", "影响类型指标单位", "LCA结果"};
        List<String[]> dataRows31 = new ArrayList<>();
        for (DocContibutionTreeEntity docContibutionTreeEntity : contributionTreeList) {
            dataRows31.add(new String[]{
                    docContibutionTreeEntity.getImpactCategoryName(),
                    docContibutionTreeEntity.getUnit(),
                    String.valueOf(docContibutionTreeEntity.getResult())
            });
        }
        TablePlaceholderReplacerUtil.replaceTablePlaceholder(doc, "{{LCA_RESULT}}",headers31,dataRows31);

        // 4 过程累积贡献分析
        List<ImpactData> impactDataList = docMapper.selectCumulativeContribution(taskId,resultId);

        QueryWrapper<TaskReportEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TaskReportEntity::getTask,taskId);
        List<TaskReportEntity> taskReportEntities = taskReportMapper.selectList(queryWrapper);

        Map<String,List<ImpactData>> impactDataListMapList = impactDataList.stream().collect(Collectors.groupingBy(ImpactData::getImpactCategoryName));


        impactDataListMapList.forEach((k,v) ->{
            // 如果 v 的数据中的 flowId 在 taskReportEntities 中数据的 tblFlowId 存在。那么保留。反之，获取v中 id 等于当前 v 数据的parentId，然后将当前 v 数据的result 累加给v中 id 等于当前 v 数据的parentId的数据的 result
            List<ImpactData> toRemove = new ArrayList<>();
            for (ImpactData i : v) {
                if (taskReportEntities.stream().noneMatch(j -> j.getTblFlowId().equals(i.getFlowId()))) {
                    v.stream().filter(j -> j.getId().equals(i.getParentId())).findFirst().ifPresent(j ->
                            j.setResult(j.getResult() + i.getResult())
                    );
                    toRemove.add(i);
                }
            }
            v.removeAll(toRemove); // 统一移除
        });

//        Map<String, Map<String, Double>> pivotTable = PivotTableConverter.convertToPivotTable(impactDataList);
        //获取所有的列名
        Set<String> allColumns = impactDataListMapList.keySet();
        List<String> columns = new ArrayList<>(allColumns);
        Collections.sort(columns);
        // 获取所有行名
        List<String> rows = impactDataListMapList.values().stream()
                .flatMap(list -> list.stream().map(ImpactData::getFlowName)).distinct().sorted().toList();

        String[] headers4 = new String[columns.size() + 1];
        headers4[0] = "工序名称";
        for (int i = 0; i < columns.size(); i++) {
            headers4[i + 1] = columns.get(i);
        }
        List<String[]> dataRows4 = new ArrayList<>();
        for (String row : rows) {
            String[] rowDataArray = new String[columns.size() + 1];
            rowDataArray[0] = row;
            for (int i = 0; i < columns.size(); i++) {
                ImpactData currentImpactData = impactDataListMapList.get(columns.get(i)).stream().filter(j -> j.getFlowName().equals(row)).findFirst().orElse(null);
                String reslutValue = String.valueOf(null!=currentImpactData?currentImpactData.getResult():0);
                rowDataArray[i + 1] = reslutValue;
            }
            dataRows4.add(rowDataArray);
        }
        TablePlaceholderReplacerUtil.replaceTablePlaceholder(doc, "{{CUMULATIVE_CONTRIBUTION}}",headers4,dataRows4);

        // 5、清单数据灵敏度分析

        List<ImpactData> impactDataList5 = docMapper.selectCumulativeContributionSensitivity(taskId,resultId);

        QueryWrapper<TaskReportEntity> queryWrapper5 = new QueryWrapper<>();
        queryWrapper5.lambda().eq(TaskReportEntity::getTask,taskId);
        List<TaskReportEntity> taskReportEntities5 = taskReportMapper.selectList(queryWrapper5);
        Map<String,String> processNameMap = new HashMap<>();
        impactDataList5.forEach(i->{
            impactDataList5.forEach(j->{
                if(j.getId().equals(i.getParentId())){
                    processNameMap.put(i.getFlowName(),j.getFlowName());
                }
            });
        });

        Map<String,List<ImpactData>> impactDataListMapList5 = impactDataList5.stream().collect(Collectors.groupingBy(ImpactData::getImpactCategoryName));


        impactDataListMapList5.forEach((k,v) ->{
            // 如果 v 的数据中的 flowId 在 taskReportEntities 中数据的 tblFlowId 存在。那么保留。反之，获取v中 id 等于当前 v 数据的parentId，然后将当前 v 数据的result 累加给v中 id 等于当前 v 数据的parentId的数据的 result
            List<ImpactData> toRemove = new ArrayList<>();
            for (ImpactData i : v) {
                if (taskReportEntities5.stream().noneMatch(j -> j.getTblFlowId().equals(i.getFlowId()))) {
                    toRemove.add(i);
                }
            }
            v.removeAll(toRemove); // 统一移除
        });

        //获取所有的列名
        Set<String> allColumns5 = impactDataListMapList5.keySet();
        List<String> columns5 = new ArrayList<>(allColumns5);
        Collections.sort(columns5);
        // 获取所有行名
        List<String> rows5 = impactDataListMapList5.values().stream()
                .flatMap(list -> list.stream().map(ImpactData::getFlowName)).distinct().sorted().toList();

        String[] headers5 = new String[columns5.size() + 1];
        headers5[0] = "所属工序";
        headers5[1] = "清单名称";
        for (int i = 1; i < columns5.size(); i++) {
            headers5[i + 1] = columns5.get(i);
        }
        List<String[]> dataRows5 = new ArrayList<>();
        for (String row : rows5) {

            String[] rowDataArray = new String[columns5.size() + 1];
            if(StringUtils.isNotBlank(processNameMap.get(row))){
                rowDataArray[0] = processNameMap.get(row);
            }else{
                rowDataArray[0] = row;
            }

            rowDataArray[1] = row;
            for (int i = 1; i < columns5.size(); i++) {

                ImpactData currentImpactData = impactDataListMapList5.get(columns5.get(i))
                        .stream().filter(j -> j.getFlowName().equals(row)).findFirst().orElse(null);

                String reslutValue = null != currentImpactData ? String.format("%.2f", currentImpactData.getScaling()) + "%" : "0.00%";
                rowDataArray[i + 1] = reslutValue;
            }
            dataRows5.add(rowDataArray);
        }
        TablePlaceholderReplacerUtil.replaceTablePlaceholder(doc, "{{DATA_SENSITIVITY}}",headers5,dataRows5);

        // 6.3 数据质量评估
        Map<Long , Map<String, Object>> simulatorResultList = simulator(tblProcessId,impactMethodId,1000);

        List<GetDataQuality> contributionTreeParentList = docMapper.selectContributionTree(resultId);
        List<DataQuality> dataQualitiesList = new ArrayList<>();
        contributionTreeParentList.forEach(i->{
            Map<String, Object> simulatorResult =simulatorResultList.get(i.getId());
            DataQuality dataQuality = new DataQuality();
            dataQuality.setImpactCategory(i.getName());
            dataQuality.setUnit(i.getUnit());
            var result = i.getResult();
            dataQuality.setValue(String.valueOf(result));
            var percentileValue5 = BigDecimal.valueOf(Double.parseDouble((String) simulatorResult.get("percentileValue5")));
            var mean = BigDecimal.valueOf(Double.parseDouble(String.valueOf(simulatorResult.get("mean"))));
            // percentileValue5 除以 mean ，保留两位小数

            var uncertainty = percentileValue5.divide(mean, 2, RoundingMode.HALF_UP);
            dataQuality.setUncertainty(String.format("%.2f", uncertainty.multiply(BigDecimal.valueOf(100)))+"%");
            // 结果上下限是result*(1加或减uncertainty)的值
            var addValue = String.valueOf(result.multiply(BigDecimal.ONE.add(uncertainty)));
            var subtractValue = String.valueOf(result.multiply(BigDecimal.ONE.subtract(uncertainty)));
            dataQuality.setInterval95("["+subtractValue+","+addValue+"]");
            dataQualitiesList.add(dataQuality);
        });
        String[] headers63 = {"指标名称", "单位", "LCA结果", "结果不确定度", "结果上下限（95%置信区间）"};
        List<String[]> dataRows63 = new ArrayList<>();
        for (DataQuality docFlowEntity : dataQualitiesList) {
            dataRows63.add(new String[]{
                    docFlowEntity.getImpactCategory(),
                    docFlowEntity.getUnit(),
                    docFlowEntity.getValue(),
                    docFlowEntity.getUncertainty(),
                    docFlowEntity.getInterval95()
            });
        }

        TablePlaceholderReplacerUtil.replaceTablePlaceholder(doc, "{{DATA_QUALITY}}",headers63,dataRows63);
        // 根据 modelId 查询模型名称
        String name = docMapper.getModelName(modelId);
        // 上传到MinIO
        String url = null;
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            doc.write(baos);
            baos.flush();
            long timestamp = System.currentTimeMillis();
            String filename = name + "_LCA报告_"+timestamp+".docx";
            String bucketName = minioProperties.getBucketName();

            try (InputStream stream = new ByteArrayInputStream(baos.toByteArray())) {
                try {
                    url = minioUtil.uploadAndGetDocUrl(baos, bucketName, filename);
                } catch (Exception e) {
                    log.error("上传文档到MinIO失败", e);
                    throw new RuntimeException("上传文档到MinIO失败", e);
                }
            }
        } finally {
            doc.close();
        }

        return GlobalResponse.of(url);
    }

    public Map<Long , Map<String, Object>> simulator(Long processId,Long impactMethodId,Integer results) {

        var db = DataDir.get().openDatabase(DerbyConfig.DBNAME);
        var system = db.get(Process.class, processId);
        var method = db.get(ImpactMethod.class, impactMethodId);
        var setup = CalculationSetup.of(system).withSimulationRuns(results).withImpactMethod(method);
        Simulator simulator = Simulator.create(setup, db);
        db.close();
        Map<Long , Map<String, Object>> resultList = new HashMap<>();
        for (var categories : method.impactCategories) {
            ImpactDescriptor gwp = Descriptor.of(categories);
            Map<String, Object> result = new HashMap<>();
//            NativeLib.loadFrom(DataDir.get().root());
            double[] values = new double[results];
            for (int i = 0; i < results; i++) {
                var r = simulator.nextRun();
                double value = r.getTotalImpactValueOf(gwp);
                values[i] = value;
                r.dispose();
            }
            Statistics stats = Statistics.of(values);

            result.put("results", String.valueOf(results));
//            result.put("values", values);
            //平均值
            result.put("mean", String.valueOf(stats.mean));
            //（标准差）方差的算术平方根
            result.put("standardDeviation", String.valueOf(stats.standardDeviation));
            //第5百分位数
            result.put("percentileValue5", String.valueOf(stats.getPercentileValue(5)));
            //第95百分位数
            result.put("percentileValue95", String.valueOf(stats.getPercentileValue(95)));
            //中位数
            result.put("median", String.valueOf(stats.median));

            System.out.println("当前的不确定分析的数据结果是: " + JSONUtil.toJsonStr( result));
            resultList.put(gwp.id, result);
        }

        return resultList;
    }

    // 替换文本
    private void replaceText(XWPFDocument doc, String placeholder, String replacement) {
        // 添加空值检查，如果replacement为null，则使用空字符串替代
        String safeReplacement = (replacement != null) ? replacement : "";

        for (XWPFParagraph p : doc.getParagraphs()) {
            for (XWPFRun r : p.getRuns()) {
                String text = r.getText(0);
                String find = placeholder;
                String replace = safeReplacement;  // 使用安全的替换值

                if (text != null && text.contains(find)) {
                    text = text.replace(find, replace);
                    r.setText(text, 0);
                }
            }
        }

        // 处理表格中的文本
        for (XWPFTable table : doc.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    for (XWPFParagraph p : cell.getParagraphs()) {
                        for (XWPFRun r : p.getRuns()) {
                            String text = r.getText(0);
                            String find = placeholder;
                            String replace = safeReplacement;  // 使用安全的替换值

                            if (text != null && text.contains(find)) {
                                text = text.replace(find, replace);
                                r.setText(text, 0);
                            }
                        }
                    }
                }
            }
        }
    }









}
